package com.trace.pplos.load.job;

import java.io.File;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.trace.pplos.load.common.Constant;
import com.trace.pplos.load.common.CosUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Project Name:pplos
 * Package Name:com.trace.pplos.load.job
 *
 * @author：zhouqilin
 * @date：2017/8/6 10:48
 * Copyright (c) 2017,jv.com.cn All Rights Reserved.
 */

@DisallowConcurrentExecution
public class DownloadJob implements Job {

    private final static Logger logger = LoggerFactory.getLogger(DownloadJob.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        long beginTime = System.currentTimeMillis();
        CosUtil cosUtil = CosUtil.getCosUtil();
        JSONArray list = cosUtil.listFolder();
        int fileCount = list.size();
        logger.info("DownloadJob start：{}，count：{}", beginTime, fileCount);
        if (fileCount > 0) {
            int corePoolSize = 5;
            int maximumPoolSize = 10;
            long keepActiveTime = 200;
            TimeUnit timeUnit = TimeUnit.SECONDS;
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(20);
            ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepActiveTime, timeUnit, workQueue);
            for (int i = 0; i < fileCount; i++) {
                JSONObject object = list.getJSONObject(i);
                logger.info("file message：{}", object);
                String fileName = object.getString("name");
                String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
                if ("zip".equalsIgnoreCase(suffix)) {
                    CosDownLoadThread thread = new CosDownLoadThread(Constant.getRootPath() + fileName, Constant.getTargetPath() + fileName + Constant.TMP, cosUtil);
                    pool.execute(thread);
                } else {
                    logger.info("DownloadJob continue，fileName：{}", fileName);
                    continue;
                }
            }
            pool.shutdown();
            while (true) {
                if (pool.isTerminated()) {
                    long diff = System.currentTimeMillis() - beginTime;
                    logger.info("DownloadJob end，count：{}，exec：{}", fileCount, (diff / 1000));
                    break;
                }
            }
        }
    }

    class CosDownLoadThread extends Thread {

        private String sourcePath;
        private String targetPath;
        private CosUtil cosUtil;

        public CosDownLoadThread(String sourcePath, String targetPath, CosUtil cosUtil) {
            this.sourcePath = sourcePath;
            this.targetPath = targetPath;
            this.cosUtil = cosUtil;
        }

        public String getSourcePath() {
            return sourcePath;
        }

        public String getTargetPath() {
            return targetPath;
        }

        public CosUtil getCosUtil() {
            return cosUtil;
        }

        @Override
        public void run() {
            boolean flag = getCosUtil().download(getSourcePath(), getTargetPath());
            if (flag) {
                new File(getTargetPath()).renameTo(new File(getTargetPath().substring(0, getTargetPath().length() - 4)));
                getCosUtil().remove(getSourcePath());
            } else {
                logger.error("download failed，file：{}", getSourcePath());
            }
        }
    }
}
